<template>
  <div class="todo-container">
    <div class="todo-wrap">
      <!--      <TodoHeader :addTodo="addTodo"/>-->
      <!--      <TodoHeader @addTodo="addTodo"/>-->
      <TodoHeader ref="header"/>
      <!--      <TodoList :todos="todos" :addTodo="addTodo" :deleteTodo="deleteTodo"/>-->
      <TodoList :todos="todos" :addTodo="addTodo"/>
      <!--      <TodoFooter :todos="todos" :deleteCompletedTodos="deleteCompletedTodos" :selectAllTodos="selectAllTodos"/>-->
      <TodoFooter>
        <input type="checkbox" v-model="isAllCheck" slot="checkAll"/>
        <span slot="count">已完成{{ completedCount }}/ 全部{{ todos.length }}</span>
        <button slot="delete" class="btn btn-danger" v-show="completedCount" @click="deleteCompletedTodos">清除已完成任务
        </button>
      </TodoFooter>
    </div>
  </div>
</template>

<script>
import TodoHeader from "./components/TodoHeader";
import TodoList from "./components/TodoList";
import TodoFooter from "./components/TodoFooter";
import PubSub from 'pubsub-js'
import storageUtils from "./util/storageUtils";

/**
 * 组件通信的几种方式：
 *  1. 通过props
 *  2. 通过自定义时间
 *    1.绑定事件 eg. <TodoHeader @addTodo="addTodo"/>
 *    2. // 触发事件 :事件名称 参数  this.$emit('addTodo',todo)
 *  3. 引入npm install --save pubsub-js  通过发布于订阅消息进行通信 以deleteTodo方法为例子
 *      1. 引入js import PubSub from 'pubsub-js'
 *      2. 在App组件订阅消息
 *      3.在TodoItem发布消息
 *     这种通信方式  可以进行多级通信
 *  4. 使用slot进行通信（slot主要是传递标签），以TodoFooter为例子进行说明
 *      1.先在TodoFooter中定义插槽
 *      2.在App中将插槽需要的标签传递过去
 *      3.在App中定义上面标签需要的参数和方法
 *
 *
 *  工具类抽取：
 *    1.将localStorage相关的方法放到一个工具类中
 *      1. 建立util文件夹跟storageUtils工具类
 *      2.将相关的方法放到工具类中
 *      3.引入工具类
 *      4.使用方法
 */
export default {
  name: "App",
  data() {
    return {
      todos: storageUtils.getTodos()
      // todos: JSON.parse(window.localStorage.getItem('todos_key') || '[]')
    }
  },
  components: {
    TodoHeader, TodoList, TodoFooter
  },
  computed: {
    completedCount() {
      return this.todos.reduce((preTotal, e) => preTotal + (e.completed ? 1 : 0), 0)
    },
    isAllCheck: {
      get() {
        return this.completedCount === this.todos.length && this.completedCount > 0
      },
      set(value) { // 这个value是当前checkbox最新的值
        this.selectAllTodos(value)
      }
    }
  },
  mounted() {
    // 通信的第3种方式
    this.$refs.header.$on('addTodo', this.addTodo)
    // 使用匿名函数后 里面的this  就是指app组件
    PubSub.subscribe('deleteTodo', (msg, index) => {
      this.deleteTodo(index)
    })
  },
  methods: {
    addTodo(newTodo) {
      this.todos.unshift(newTodo)
    },
    deleteTodo(index) {
      this.todos.splice(index, 1)
    },
    deleteCompletedTodos() {
      this.todos = this.todos.filter(e => !e.completed)
    },
    selectAllTodos(check) {
      this.todos.forEach(e => e.completed = check)
    }
  },
  watch: {
    todos: {
      deep: true,
      /* handler: function (value) {
         // window.localStorage.setItem('todos_key', JSON.stringify(value))
         storageUtils.saveTodos(value)
       }*/
      // 简化写法
      handler: storageUtils.saveTodos
    }
  }
}
</script>

<style scoped>
/*app*/
.todo-container {
  width: 600px;
  margin: 0 auto;
}

.todo-container .todo-wrap {
  padding: 10px;
  border: 1px solid #ddd;
  border-radius: 5px;
}

</style>
